package com.example.gaojt.androiddemo.webViewStudy;

import android.app.Activity;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
import android.net.Uri;
import android.net.http.SslError;
import android.os.Bundle;
import android.os.Message;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.webkit.ClientCertRequest;
import android.webkit.ConsoleMessage;
import android.webkit.GeolocationPermissions;
import android.webkit.HttpAuthHandler;
import android.webkit.JsPromptResult;
import android.webkit.JsResult;
import android.webkit.PermissionRequest;
import android.webkit.SslErrorHandler;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceError;
import android.webkit.WebResourceRequest;
import android.webkit.WebResourceResponse;
import android.webkit.WebSettings;
import android.webkit.WebStorage;
import android.webkit.WebView;
import android.webkit.WebViewClient;

import com.example.gaojt.androiddemo.R;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by gaojt on 6/22/17.
 */

public class WebViewStudyActivity extends Activity {
    private static final String TAG = "WebViewStudyActivity";
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.webview_study_ly);
        WebView webView1 = (WebView) findViewById(R.id.webview1);
        Log.d(TAG, "onCreate: webView1 = " + webView1);
        initWebSetting(webView1);
        webView1.setWebViewClient(new WebViewClient(){

            @Override
            public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
                Log.d(TAG, "shouldOverrideUrlLoading: request = " + request);
                return true;
            }

            @Override
            public void onReceivedClientCertRequest(WebView view, ClientCertRequest request) {
                Log.d(TAG, "onReceivedClientCertRequest: ");
                super.onReceivedClientCertRequest(view, request);
            }

            @Override
            public void onPageCommitVisible(WebView view, String url) {
                Log.d(TAG, "onPageCommitVisible: url = " + url);
                super.onPageCommitVisible(view, url);
            }

            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                Log.d(TAG, "onPageStarted: url = " + url,new Exception());
                super.onPageStarted(view, url, favicon);
            }

            @Override
            public void onPageFinished(WebView view, String url) {
                Log.d(TAG, "onPageFinished: url = " + url,new Exception());
                super.onPageFinished(view, url);
            }

            @Override
            public void onFormResubmission(WebView view, Message dontResend, Message resend) {
                super.onFormResubmission(view, dontResend, resend);
            }

            @Override
            public void onLoadResource(WebView view, String url) {
                Log.d(TAG, "onLoadResource: url = " + url);
                super.onLoadResource(view, url);
            }

            @Override
            public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {
                Log.d(TAG, "onReceivedHttpError: ");
                super.onReceivedHttpError(view, request, errorResponse);
            }

            @Override
            public void onUnhandledKeyEvent(WebView view, KeyEvent event) {
                Log.d(TAG, "onUnhandledKeyEvent: ");
                super.onUnhandledKeyEvent(view, event);
            }

            @Override
            public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm) {
                Log.d(TAG, "onReceivedHttpAuthRequest: ");
                super.onReceivedHttpAuthRequest(view, handler, host, realm);
            }

            @Override
            public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
                Log.d(TAG, "onReceivedError: ");
                super.onReceivedError(view, request, error);
            }

            @Override
            public void onReceivedLoginRequest(WebView view, String realm, String account, String args) {
                Log.d(TAG, "onReceivedLoginRequest: ");
                super.onReceivedLoginRequest(view, realm, account, args);
            }

            @Override
            public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
                Log.d(TAG, "onReceivedSslError: ");
                super.onReceivedSslError(view, handler, error);
            }

        });

        WebChromeClient client = new WebChromeClient() {

            /**
             * Tell the host application the current progress of loading a page.
             * @param view The WebView that initiated the callback.
             * @param newProgress Current page loading progress, represented by
             *                    an integer between 0 and 100.
             */
            public void onProgressChanged(WebView view, int newProgress) {
                Log.d(TAG, "onProgressChanged: newProgress = " + newProgress);
            }

            /**
             * Notify the host application of a change in the document title.
             * @param view The WebView that initiated the callback.
             * @param title A String containing the new title of the document.
             */
            public void onReceivedTitle(WebView view, String title) {
                Log.d(TAG, "onReceivedTitle: title = " + title);
            }

            /**
             * Notify the host application of a new favicon for the current page.
             * @param view The WebView that initiated the callback.
             * @param icon A Bitmap containing the favicon for the current page.
             */
            public void onReceivedIcon(WebView view, Bitmap icon) {
                
            }

            /**
             * Notify the host application of the url for an apple-touch-icon.
             * @param view The WebView that initiated the callback.
             * @param url The icon url.
             * @param precomposed True if the url is for a precomposed touch icon.
             */
            public void onReceivedTouchIconUrl(WebView view, String url,
                                               boolean precomposed) {
                Log.d(TAG, "onReceivedTouchIconUrl: url = " + url + ",precomposed = " + precomposed);
            }

            /**
             * Notify the host application that the current page has entered full
             * screen mode. The host application must show the custom View which
             * contains the web contents &mdash; video or other HTML content &mdash;
             * in full screen mode. Also see "Full screen support" documentation on
             * {@link WebView}.
             * @param view is the View object to be shown.
             * @param callback invoke this callback to request the page to exit
             * full screen mode.
             */
            public void onShowCustomView(View view, CustomViewCallback callback) {
                Log.d(TAG, "onShowCustomView: ");
            };

            /**
             * Notify the host application that the current page would
             * like to show a custom View in a particular orientation.
             * @param view is the View object to be shown.
             * @param requestedOrientation An orientation constant as used in
             * {@link ActivityInfo#screenOrientation ActivityInfo.screenOrientation}.
             * @param callback is the callback to be invoked if and when the view
             * is dismissed.
             * @deprecated This method supports the obsolete plugin mechanism,
             * and will not be invoked in future
             */
            @Deprecated
            public void onShowCustomView(View view, int requestedOrientation,
                                         CustomViewCallback callback) {
                Log.d(TAG, "onShowCustomView: ");
            };

            /**
             * Notify the host application that the current page has exited full
             * screen mode. The host application must hide the custom View, ie. the
             * View passed to {@link #onShowCustomView} when the content entered fullscreen.
             * Also see "Full screen support" documentation on {@link WebView}.
             */
            public void onHideCustomView() {}

            /**
             * Request the host application to create a new window. If the host
             * application chooses to honor this request, it should return true from
             * this method, create a new WebView to host the window, insert it into the
             * View system and send the supplied resultMsg message to its target with
             * the new WebView as an argument. If the host application chooses not to
             * honor the request, it should return false from this method. The default
             * implementation of this method does nothing and hence returns false.
             * @param view The WebView from which the request for a new window
             *             originated.
             * @param isDialog True if the new window should be a dialog, rather than
             *                 a full-size window.
             * @param isUserGesture True if the request was initiated by a user gesture,
             *                      such as the user clicking a link.
             * @param resultMsg The message to send when once a new WebView has been
             *                  created. resultMsg.obj is a
             *                  {@link WebView.WebViewTransport} object. This should be
             *                  used to transport the new WebView, by calling
             *                  {@link WebView.WebViewTransport#setWebView(WebView)
             *                  WebView.WebViewTransport.setWebView(WebView)}.
             * @return This method should return true if the host application will
             *         create a new window, in which case resultMsg should be sent to
             *         its target. Otherwise, this method should return false. Returning
             *         false from this method but also sending resultMsg will result in
             *         undefined behavior.
             */
            public boolean onCreateWindow(WebView view, boolean isDialog,
                                          boolean isUserGesture, Message resultMsg) {
                Log.d(TAG, "onCreateWindow: ");
                return false;
            }

            /**
             * Request display and focus for this WebView. This may happen due to
             * another WebView opening a link in this WebView and requesting that this
             * WebView be displayed.
             * @param view The WebView that needs to be focused.
             */
            public void onRequestFocus(WebView view) {
                Log.d(TAG, "onRequestFocus: ");
            }

            /**
             * Notify the host application to close the given WebView and remove it
             * from the view system if necessary. At this point, WebCore has stopped
             * any loading in this window and has removed any cross-scripting ability
             * in javascript.
             * @param window The WebView that needs to be closed.
             */
            public void onCloseWindow(WebView window) {
                Log.d(TAG, "onCloseWindow: ");
            }

            /**
             * Tell the client to display a javascript alert dialog.  If the client
             * returns true, WebView will assume that the client will handle the
             * dialog.  If the client returns false, it will continue execution.
             * @param view The WebView that initiated the callback.
             * @param url The url of the page requesting the dialog.
             * @param message Message to be displayed in the window.
             * @param result A JsResult to confirm that the user hit enter.
             * @return boolean Whether the client will handle the alert dialog.
             */
            public boolean onJsAlert(WebView view, String url, String message,
                                     JsResult result) {
                Log.d(TAG, "onJsAlert: ");
                return true;
            }

            /**
             * Tell the client to display a confirm dialog to the user. If the client
             * returns true, WebView will assume that the client will handle the
             * confirm dialog and call the appropriate JsResult method. If the
             * client returns false, a default value of false will be returned to
             * javascript. The default behavior is to return false.
             * @param view The WebView that initiated the callback.
             * @param url The url of the page requesting the dialog.
             * @param message Message to be displayed in the window.
             * @param result A JsResult used to send the user's response to
             *               javascript.
             * @return boolean Whether the client will handle the confirm dialog.
             */
            public boolean onJsConfirm(WebView view, String url, String message,
                                       JsResult result) {
                Log.d(TAG, "onJsConfirm: ");
                return true;
            }

            /**
             * Tell the client to display a prompt dialog to the user. If the client
             * returns true, WebView will assume that the client will handle the
             * prompt dialog and call the appropriate JsPromptResult method. If the
             * client returns false, a default value of false will be returned to to
             * javascript. The default behavior is to return false.
             * @param view The WebView that initiated the callback.
             * @param url The url of the page requesting the dialog.
             * @param message Message to be displayed in the window.
             * @param defaultValue The default value displayed in the prompt dialog.
             * @param result A JsPromptResult used to send the user's reponse to
             *               javascript.
             * @return boolean Whether the client will handle the prompt dialog.
             */
            public boolean onJsPrompt(WebView view, String url, String message,
                                      String defaultValue, JsPromptResult result) {
                Log.d(TAG, "onJsPrompt: ");
                return true;
            }

            /**
             * Tell the client to display a dialog to confirm navigation away from the
             * current page. This is the result of the onbeforeunload javascript event.
             * If the client returns true, WebView will assume that the client will
             * handle the confirm dialog and call the appropriate JsResult method. If
             * the client returns false, a default value of true will be returned to
             * javascript to accept navigation away from the current page. The default
             * behavior is to return false. Setting the JsResult to true will navigate
             * away from the current page, false will cancel the navigation.
             * @param view The WebView that initiated the callback.
             * @param url The url of the page requesting the dialog.
             * @param message Message to be displayed in the window.
             * @param result A JsResult used to send the user's response to
             *               javascript.
             * @return boolean Whether the client will handle the confirm dialog.
             */
            public boolean onJsBeforeUnload(WebView view, String url, String message,
                                            JsResult result) {
                Log.d(TAG, "onJsBeforeUnload: ");
                return true;
            }

            /**
             * Tell the client that the quota has been exceeded for the Web SQL Database
             * API for a particular origin and request a new quota. The client must
             * respond by invoking the
             * {@link WebStorage.QuotaUpdater#updateQuota(long) updateQuota(long)}
             * method of the supplied {@link WebStorage.QuotaUpdater} instance. The
             * minimum value that can be set for the new quota is the current quota. The
             * default implementation responds with the current quota, so the quota will
             * not be increased.
             * @param url The URL of the page that triggered the notification
             * @param databaseIdentifier The identifier of the database where the quota
             *                           was exceeded.
             * @param quota The quota for the origin, in bytes
             * @param estimatedDatabaseSize The estimated size of the offending
             *                              database, in bytes
             * @param totalQuota The total quota for all origins, in bytes
             * @param quotaUpdater An instance of {@link WebStorage.QuotaUpdater} which
             *                     must be used to inform the WebView of the new quota.
             * @deprecated This method is no longer called; WebView now uses the HTML5 / JavaScript Quota
             *             Management API.
             */
            @Deprecated
            public void onExceededDatabaseQuota(String url, String databaseIdentifier,
                                                long quota, long estimatedDatabaseSize, long totalQuota,
                                                WebStorage.QuotaUpdater quotaUpdater) {
                // This default implementation passes the current quota back to WebCore.
                // WebCore will interpret this that new quota was declined.
                Log.d(TAG, "onExceededDatabaseQuota: ");
                quotaUpdater.updateQuota(quota);
            }

            /**
             * Notify the host application that the Application Cache has reached the
             * maximum size. The client must respond by invoking the
             * {@link WebStorage.QuotaUpdater#updateQuota(long) updateQuota(long)}
             * method of the supplied {@link WebStorage.QuotaUpdater} instance. The
             * minimum value that can be set for the new quota is the current quota. The
             * default implementation responds with the current quota, so the quota will
             * not be increased.
             * @param requiredStorage The amount of storage required by the Application
             *                        Cache operation that triggered this notification,
             *                        in bytes.
             * @param quota the current maximum Application Cache size, in bytes
             * @param quotaUpdater An instance of {@link WebStorage.QuotaUpdater} which
             *                     must be used to inform the WebView of the new quota.
             * @deprecated This method is no longer called; WebView now uses the HTML5 / JavaScript Quota
             *             Management API.
             */
            @Deprecated
            public void onReachedMaxAppCacheSize(long requiredStorage, long quota,
                                                 WebStorage.QuotaUpdater quotaUpdater) {
                Log.d(TAG, "onReachedMaxAppCacheSize: ");
                quotaUpdater.updateQuota(quota);
            }

            /**
             * Notify the host application that web content from the specified origin
             * is attempting to use the Geolocation API, but no permission state is
             * currently set for that origin. The host application should invoke the
             * specified callback with the desired permission state. See
             * {@link GeolocationPermissions} for details.
             *
             * <p>Note that for applications targeting Android N and later SDKs
             * (API level > {@link android.os.Build.VERSION_CODES#M})
             * this method is only called for requests originating from secure
             * origins such as https. On non-secure origins geolocation requests
             * are automatically denied.</p>
             *
             * @param origin The origin of the web content attempting to use the
             *               Geolocation API.
             * @param callback The callback to use to set the permission state for the
             *                 origin.
             */
            public void onGeolocationPermissionsShowPrompt(String origin,
                                                           GeolocationPermissions.Callback callback) {
                Log.d(TAG, "onGeolocationPermissionsShowPrompt: ");
            }

            /**
             * Notify the host application that a request for Geolocation permissions,
             * made with a previous call to
             * {@link #onGeolocationPermissionsShowPrompt(String,GeolocationPermissions.Callback) onGeolocationPermissionsShowPrompt()}
             * has been canceled. Any related UI should therefore be hidden.
             */
            public void onGeolocationPermissionsHidePrompt() {
                Log.d(TAG, "onGeolocationPermissionsHidePrompt: ");
            }

            /**
             * Notify the host application that web content is requesting permission to
             * access the specified resources and the permission currently isn't granted
             * or denied. The host application must invoke {@link PermissionRequest#grant(String[])}
             * or {@link PermissionRequest#deny()}.
             *
             * If this method isn't overridden, the permission is denied.
             *
             * @param request the PermissionRequest from current web content.
             */
            public void onPermissionRequest(PermissionRequest request) {
                Log.d(TAG, "onPermissionRequest: ");
                request.deny();
            }

            /**
             * Notify the host application that the given permission request
             * has been canceled. Any related UI should therefore be hidden.
             *
             * @param request the PermissionRequest that needs be canceled.
             */
            public void onPermissionRequestCanceled(PermissionRequest request) {
                Log.d(TAG, "onPermissionRequestCanceled: ");
            }

            /**
             * Tell the client that a JavaScript execution timeout has occured. And the
             * client may decide whether or not to interrupt the execution. If the
             * client returns true, the JavaScript will be interrupted. If the client
             * returns false, the execution will continue. Note that in the case of
             * continuing execution, the timeout counter will be reset, and the callback
             * will continue to occur if the script does not finish at the next check
             * point.
             * @return boolean Whether the JavaScript execution should be interrupted.
             * @deprecated This method is no longer supported and will not be invoked.
             */
            // This method was only called when using the JSC javascript engine. V8 became
            // the default JS engine with Froyo and support for building with JSC was
            // removed in b/5495373. V8 does not have a mechanism for making a callback such
            // as this.
            public boolean onJsTimeout() {
                Log.d(TAG, "onJsTimeout: ");
                return true;
            }

            /**
             * Report a JavaScript error message to the host application. The ChromeClient
             * should override this to process the log message as they see fit.
             * @param message The error message to report.
             * @param lineNumber The line number of the error.
             * @param sourceID The name of the source file that caused the error.
             * @deprecated Use {@link #onConsoleMessage(ConsoleMessage) onConsoleMessage(ConsoleMessage)}
             *      instead.
             */
            @Deprecated
            public void onConsoleMessage(String message, int lineNumber, String sourceID) {
                Log.d(TAG, "onConsoleMessage: ");
            }

            /**
             * Report a JavaScript console message to the host application. The ChromeClient
             * should override this to process the log message as they see fit.
             * @param consoleMessage Object containing details of the console message.
             * @return true if the message is handled by the client.
             */
            public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
                // Call the old version of this function for backwards compatability.
                onConsoleMessage(consoleMessage.message(), consoleMessage.lineNumber(),
                        consoleMessage.sourceId());
                return false;
            }

            /**
             * When not playing, video elements are represented by a 'poster' image. The
             * image to use can be specified by the poster attribute of the video tag in
             * HTML. If the attribute is absent, then a default poster will be used. This
             * method allows the ChromeClient to provide that default image.
             *
             * @return Bitmap The image to use as a default poster, or null if no such image is
             * available.
             */
            public Bitmap getDefaultVideoPoster() {
                return null;
            }

            /**
             * Obtains a View to be displayed while buffering of full screen video is taking
             * place. The host application can override this method to provide a View
             * containing a spinner or similar.
             *
             * @return View The View to be displayed whilst the video is loading.
             */
            public View getVideoLoadingProgressView() {
                return null;
            }

            /** Obtains a list of all visited history items, used for link coloring
             */
            public void getVisitedHistory(ValueCallback<String[]> callback) {
            }

            /**
             * Tell the client to show a file chooser.
             *
             * This is called to handle HTML forms with 'file' input type, in response to the
             * user pressing the "Select File" button.
             * To cancel the request, call <code>filePathCallback.onReceiveValue(null)</code> and
             * return true.
             *
             * @param webView The WebView instance that is initiating the request.
             * @param filePathCallback Invoke this callback to supply the list of paths to files to upload,
             *                         or NULL to cancel. Must only be called if the
             *                         <code>showFileChooser</code> implementations returns true.
             * @param fileChooserParams Describes the mode of file chooser to be opened, and options to be
             *                          used with it.
             * @return true if filePathCallback will be invoked, false to use default handling.
             *
             * @see FileChooserParams
             */
            public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback,
                                             FileChooserParams fileChooserParams) {
                Log.d(TAG, "onShowFileChooser: ");
                return false;
            }

        };
//        webView1.setWebChromeClient(client);
//        webView1.loadUrl("http://m.xhubs.tv/");
        Map<String,String> extraHeaders = new HashMap<String, String>();
        extraHeaders.put("Referer", "http://m.xhubs.tv");
        webView1.loadUrl("http://m.xhubs.tv/detail/1535819",extraHeaders);
//        WebView webView2 = (WebView) findViewById(R.id.webview2);
//        webView2.setWebViewClient(new WebViewClient(){
//            @Override
//            public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
//                Log.d(TAG, "shouldOverrideUrlLoading: request = " + request);
//                return true;
//            }
//
//
//
//            @Override
//            public void onPageStarted(WebView view, String url, Bitmap favicon) {
//                Log.d(TAG, "onPageStarted: url = " + url);
//                super.onPageStarted(view, url, favicon);
//            }
//
//            @Override
//            public void onPageFinished(WebView view, String url) {
//                Log.d(TAG, "onPageFinished: url = " + url);
//                super.onPageFinished(view, url);
//            }
//        });
//        initWebSetting(webView2);
//        webView2.loadUrl("https://www.baidu.com");
    }

    public void initWebSetting(WebView webView) {
        webView.requestFocus();
        webView.setSelected(true);
        webView.setScrollBarStyle(View.SCROLLBARS_OUTSIDE_OVERLAY);
        WebSettings webSettings = webView.getSettings();
        webSettings.setJavaScriptEnabled(true);
        webSettings.setSupportZoom(true);
        webSettings.setBuiltInZoomControls(true);
        webSettings.setUseWideViewPort(true);
        webSettings.setLoadWithOverviewMode(true);
        initCache(webView);
    }

    private void initCache(WebView webView) {
        WebSettings webSettings = webView.getSettings();
        webSettings.setAppCacheEnabled(true);
        webSettings.setDatabaseEnabled(true);
        webSettings.setDomStorageEnabled(true);
        webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);
        webSettings.setAppCachePath(this.getDir("web_appcache", Context.MODE_PRIVATE).getPath());
    }
}
